﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Diagnostics;
using System.Transactions;
using System.Xml.Linq;
using TextToSpeech;
using static TextToSpeech.BaiduTranslation;

namespace CSharpScriptCommentsTranslation
{
    internal class Program
    {
        static void Main(string[] args)
        {
            BaiduTranslation baiduTranslation = new BaiduTranslation();
            baiduTranslation.To = Languages.中文_简体;
            //Roslyn 

            if (args.Length != 0)
            {

                foreach (var path in GetAllFilesPath(args[0]))
                {
                    string code = File.ReadAllText(path);
                    SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
                    //注释
                    CompilationUnitSyntax rootNode =  tree.GetCompilationUnitRoot();

                   

                    var trivias = rootNode.DescendantTrivia();
                    List<SyntaxTrivia> originalTrivias = new List<SyntaxTrivia>();
                    List<SyntaxTrivia> newTrivias = new List<SyntaxTrivia>();

                    var g = trivias.ToArray();

                    List<string> comments = new List<string>();
                    //做一个空白琐事缓存
                    SyntaxTrivia whitespaceTriviaCashe = default;

                    foreach (var trivia in trivias)
                    {
                        if(trivia.IsKind(SyntaxKind.WhitespaceTrivia))
                        {
                            whitespaceTriviaCashe = trivia;
                        }
                        else if(trivia.IsKind(SyntaxKind.SingleLineCommentTrivia))
                        {
                            string trans = baiduTranslation.GetTranslation(trivia.ToFullString(), Languages.英语);//翻译文档
                            //var originalLines = trivia.ToFullString().Split("\n", StringSplitOptions.RemoveEmptyEntries);//切成line
                            //var translines = trans.Split("\n", StringSplitOptions.RemoveEmptyEntries);
                            string save = string.Empty;
                            save += trivia.ToFullString();
                            save += "\n";

                            //for (int i = 0; i < translines.Length; i++)
                            //{
                                int spacesBefore = trivia.ToFullString().TakeWhile(char.IsWhiteSpace).Count();
                                if(whitespaceTriviaCashe.IsKind(SyntaxKind.WhitespaceTrivia))
                                {
                                    spacesBefore = whitespaceTriviaCashe.ToFullString().Length;
                                }

                                // Find the index of '///' and count spaces after it until the actual comment starts
                                int indexOfComment = trivia.ToFullString().IndexOf("///") + 3; // Move past '///'
                                int spacesAfter = trivia.ToFullString().Skip(indexOfComment).TakeWhile(char.IsWhiteSpace).Count();

                                string before = new string(' ', spacesBefore);
                                string after = new string(' ', spacesAfter);

                                var saveTrans = before + "//" + after + trans.Remove(0, 2);
                                save += saveTrans.Remove(saveTrans.Length-1);//移出换行符

                                //save += "\n";
                            //}

                            SyntaxTrivia newSyntaxTrivia = SyntaxFactory.Comment(save);
                            originalTrivias.Add(trivia);
                            newTrivias.Add(newSyntaxTrivia);
                        }
                        else if (trivia.IsKind(SyntaxKind.MultiLineCommentTrivia))
                        {
                            //稍微有些许对称问题，但无伤大雅
                            string trans = baiduTranslation.GetTranslation(trivia.ToString());
                            SyntaxTrivia newSyntaxTrivia = SyntaxFactory.Comment(trans);
                            originalTrivias.Add(trivia);
                            newTrivias.Add(newSyntaxTrivia);

                        }
                        else if (trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia))
                         {
                            string trans = baiduTranslation.GetTranslation(trivia.ToFullString(), Languages.英语);//翻译文档
                            var originalLines =  trivia.ToFullString().Split("\n",StringSplitOptions.RemoveEmptyEntries);//切成line
                            var translines = trans.Split("\n", StringSplitOptions.RemoveEmptyEntries);
                            string save = string.Empty;

                            if (originalLines[0].Contains("<summary>"))//有概要头
                            {
                                save += originalLines[0];
                                save += "\n";

                                
                                ///先添加原始文本
                                for (int i = 1 ; i < originalLines.Length - 1;i++)
                                {
                                    save += originalLines[i];
                                    save += "\n";
                                }
                                ///再添加被翻译文本
                                for (int i = 1; i < translines.Length - 1; i++)
                                {
                                    int spacesBefore = originalLines[i].TakeWhile(char.IsWhiteSpace).Count();
                                    // Find the index of '///' and count spaces after it until the actual comment starts
                                    int indexOfComment = originalLines[i].IndexOf("///") + 3; // Move past '///'
                                    int spacesAfter = originalLines[i].Skip(indexOfComment).TakeWhile(char.IsWhiteSpace).Count();

                                    string before = new string(' ', spacesBefore);
                                    string after = new string(' ', spacesAfter);

                                    var saveTrans = before +"///"+ after +  translines[i].Remove(0, 3);
                                    save += saveTrans;
                                    save += "\n";
                                }
                                save += originalLines[originalLines.Length - 1];
                            }
                            else
                            {
                                save += trivia.ToFullString();

                                for (int i = 0; i < translines.Length; i++)
                                {
                                    int spacesBefore = originalLines[i].TakeWhile(char.IsWhiteSpace).Count();
                                    if (whitespaceTriviaCashe.IsKind(SyntaxKind.WhitespaceTrivia))
                                    {
                                        spacesBefore = whitespaceTriviaCashe.ToFullString().Length;
                                    }
                                    // Find the index of '///' and count spaces after it until the actual comment starts
                                    int indexOfComment = originalLines[i].IndexOf("///") + 3; // Move past '///'
                                    int spacesAfter = originalLines[i].Skip(indexOfComment).TakeWhile(char.IsWhiteSpace).Count();

                                    string before = new string(' ', spacesBefore);
                                    string after = new string(' ', spacesAfter);

                                    var saveTrans = before + "///" + after + translines[i].Remove(0, 3);
                                    save += saveTrans;
                                    save += "\n";
                                }





                            }

                            SyntaxTrivia newSyntaxTrivia = SyntaxFactory.Comment(save);
                            originalTrivias.Add(trivia);
                            newTrivias.Add(newSyntaxTrivia);

                            //SyntaxFactory.Trivia(new st);
                            //rootNode = rootNode.ReplaceTrivia(trivia, newSyntaxTrivia);

                        }
                        else if (trivia.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia))
                        {
                            Console.WriteLine($"暂未添加对{SyntaxKind.MultiLineDocumentationCommentTrivia}的翻译支持");
                            //string trans = baiduTranslation.GetTranslation(trivia.ToString());
                        }
                        else
                        {
                            whitespaceTriviaCashe = default;//自动清空
                        }

                    }

                    int index = 0;
                    rootNode = rootNode.ReplaceTrivia(originalTrivias, ReplaceTriviaFuc);

                    SyntaxTrivia ReplaceTriviaFuc(SyntaxTrivia syntaxTrivia, SyntaxTrivia temp)
                    {
                        temp = newTrivias[index];
                        index++;
                        return temp;
                    }

                    //rootNode.ReplaceNodes(newTrivias);
                    //rootNode.ReplaceTrivia()
                    //需要一次性修改所有的树



                    switch(args[1])
                    {
                        case "0":
                            {
                                var saveFile = File.CreateText(path);
                                saveFile.Write(rootNode.ToFullString());
                                Console.WriteLine($"文件{path}覆盖");
                                saveFile.Close();

                            }
                            break;
                        case "1":
                            {
                                //需要建一个副本-Translate

                                string subPath = path.Substring(args[0].Length);
                                string savePath = $"{args[0]}-Translate{subPath}";
                                Directory.CreateDirectory(Path.GetDirectoryName(savePath));

                                //var dir = Path.GetDirectoryName(path);
                                //string name = Path.GetFileNameWithoutExtension(path);
                                var saveFile = File.CreateText(savePath);
                                Console.WriteLine($"文件{savePath}已保存");
                                saveFile.Write(rootNode.ToFullString());
                                saveFile.Close();

                            }
                            break;
                    }

                }
            }
            else
            {
                Console.Write("未能识别到命令行参数，请在目录中写出需要翻译的.cs文件夹以及模式" +
                    "填写参数为0:覆盖原有.cs文件" +
                    "填写参数位1:在路径旁生成副本");
            }
        }

        /// <summary>
        /// 注释
        /// </summary>
        /// <param name="Path"></param>
        /// <returns></returns>
        static IEnumerable<string> GetAllFilesPath(string Path)
        {

            var filePaths = Directory.GetFiles(Path);

            for (int i = 0; i < filePaths.Length; i++)
            {

                yield return filePaths[i];
            }
           var dirPaths = Directory.GetDirectories(Path);
            for (int i = 0; i < dirPaths.Length; i++)
            {
                foreach (var dirPath in dirPaths)
                {
                    foreach(var data in GetAllFilesPath(dirPath))
                    {
                        yield return data;
                    }
                   
                }
               
            }
        }
    }

    
}